package org.bdware.doip.endpoint.doipServer;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.bdware.doip.core.crypto.GlobalCertifications;
import org.bdware.doip.core.model.digitalObject.DigitalObject;
import org.bdware.doip.core.model.digitalObject.DoType;
import org.bdware.irp.stateinfo.DoipServiceStateInfo;

import java.net.URI;
import java.util.List;

public class DoipServiceInfo {
    public String id;
    public String serviceDescription;
    public String publicKey;
    public String serviceName;
    public int port;
    public String ipAddress;
    public String protocol;
    public String protocolVersion;
    public List<DoipListenerInfo> listenerInfos;
    public String owner;
    public String repoType;

    public DoipServiceInfo(String id, String owner, String repoType, List<DoipListenerInfo> listenerInfos){
        this.id = id;
        this.owner = owner;
        this.repoType = repoType;
        this.listenerInfos = listenerInfos;
        String url = listenerInfos.get(0).url;
        URI uri = URI.create(url);
        protocol = uri.getScheme();
        ipAddress = uri.getHost();
        port = uri.getPort();
        protocolVersion = listenerInfos.get(0).protocolVersion;
        this.publicKey = GlobalCertifications.getGlobalJWK().toPublicJWK().toString();
    }

    public static DoipServiceInfo fromJson(String str) {
        return new Gson().fromJson(str, DoipServiceInfo.class);
    }

    public String toJson(){
        return new Gson().toJson(this);
    }

    public byte[] toBytes(){
        return this.toJson().getBytes();
    }

    public DigitalObject toDigitalObject(){

        DigitalObject dObj = new DigitalObject(this.id, DoType.DOIPServiceInfo);
        dObj.addAttribute("serviceName", serviceName);
        dObj.addAttribute("serviceDescription",serviceDescription);
        dObj.addAttribute("owner",owner);
        dObj.addAttribute("repoType",repoType);
        dObj.addAttribute("publicKey",publicKey);
        dObj.addAttribute("protocol",protocol);
        dObj.addAttribute("protocolVersion",protocolVersion);
        dObj.addAttribute("port",port);
        dObj.addAttribute("ipAddress",ipAddress);
        dObj.addAttribute("listenerInfos",new Gson().toJson(listenerInfos));
        return dObj;
    }

    public static DoipServiceInfo fromDigitalObject(DigitalObject dObj) {
        List<DoipListenerInfo> ss = new Gson().fromJson(dObj.attributes.get("listenerInfos").getAsString(),
                new TypeToken<List<DoipListenerInfo>>(){}.getType());
        DoipServiceInfo serviceInfo = new DoipServiceInfo(
                dObj.id,
                dObj.attributes.get("owner").getAsString(),
                dObj.attributes.get("repoType").getAsString(),
                ss
        );
        serviceInfo.serviceName = dObj.attributes.get("serviceName") == null?"":dObj.attributes.get("serviceName").getAsString();
        serviceInfo.publicKey = dObj.attributes.get("publicKey") == null?"":dObj.attributes.get("publicKey").getAsString();
        serviceInfo.serviceDescription = dObj.attributes.get("serviceDescription") == null?"":dObj.attributes.get("serviceDescription").getAsString();
        serviceInfo.repoType = dObj.attributes.get("repoType") == null?"":dObj.attributes.get("repoType").getAsString();

        return serviceInfo;
    }

    public DoipServiceStateInfo toServiceHandleRecord(){
        DoipServiceStateInfo service = new DoipServiceStateInfo(
                this.serviceName,this.serviceDescription,this.owner,new Gson().toJson(this.listenerInfos),this.publicKey,this.repoType);
        service.identifier = this.id;
        return service;
    }
}
